#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1996-09-04 11:27 JST by <kono@leo.ie.u-ryukyu.ac.jp>.
# Source directory was `/user/kono/src/vbox'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#  36062 -rw-r--r-- visca.pl
#  16318 -rw-r--r-- visca.man
#    226 -rwxr-xr-x examples/md_off.pl
#    283 -rwxr-xr-x examples/md_timer.pl
#     59 -rw-r--r-- examples/test0.pl
#    218 -rwxr-xr-x examples/vcr_off.pl
#    234 -rwxr-xr-x examples/vcr_on.pl
#    316 -rwxr-xr-x examples/vcr_reserve.pl
#    239 -rwxr-xr-x examples/vcr_timer.pl
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
# ============= visca.pl ==============
if test -f 'visca.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping visca.pl (file already exists)'
else
  echo 'x - extracting visca.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'visca.pl' &&
# Visca Command Generator
#   $Id: visca.pl,v 1.9 1996/01/06 16:50:51 kono Exp kono $
X
package Visca;
X
$source = "./visca.pl";
X
##########################################################
# Visca Communication Part
#    LANC Command Handshake
##########################################################
X
$check_time = 0.5;
X
sub send {
X    local($out) = pack("H*",$_[0]);
X    local($check) = $_[1] ? $_[1] : $check_time;
X    local($/) = "\377";
X
X    if($_[0] =~ /error/) { print STDERR $_[0],"\n"; return ""; }
X    $input = ''; 
X    syswrite(TTY,$out,length($out));
X
X    ($nfound,$timeleft) =
X	    select($sout=$vin, $wout=$null, $eout=$null, $check);
X    # first busy wait for immediate reply by busy wait
X    $input .= <TTY> until ($input =~ /\377$/); 
X    push(@input_buf,$input);   # it may not be the ack, error or other
X    return &check_reply($check);
}
X
sub check_reply {
X    local($check) = $_[0] ? $_[0] : $check_time;
X    $input = ''; 
X    # check immediate completion for a while
X    while( ($nfound,$timeleft) =
X	    select($sout=$vin, $wout=$null, $eout=$null, $check)) {
X	last if (! $nfound);
X	$input .= <TTY> until ($input =~ /\377$/); 
X	push(@input_buf,$input);
X	$input = '';
X    }
X
X    # process replies
X
X    $ack = '';
X    while($_ = unpack("H*",shift(@input_buf))) {
X	# possibly concatenated
X	while($_) {
X	    if(s/([9a-f])04(.)ff//) {          # Ack
X		$ack= ($1-8) . "-$2"; $busy{$ack} = 1;
X		next;
X	    } elsif (s/([9a-f])05(.)ff//) {      # Completion
X		$compl= ($1-8) . "-$2"; delete $busy{$compl};
X		next;
X	    } elsif (s/[9a-f]06.*ff//) {      # Error
X		$error = &Error($&);
X		unshift(@input_buf,$_); # unprocessed input_buf left
X		return 0;
X	    } elsif (s/[9a-f]038ff//) {      # Network change
X		if(&send(&Address) !~ /^883/) {
X		    $_ = &check_reply while (! /^883/);
X		}
X		next;
X	    } elsif(s/.*ff//) {
X		# immediate reply
X		unshift(@input_buf,$_); # unprocessed input_buf left
X		return $&;
X	    }
X	    last;
X	    # discard unknown
X	}
X    }
X    return $ack;
X    # completion can be checked by $busy{$ack}
}
X
sub open_visca {
X
X    &Init;
X    if(! &send(&IF_Clear)) { print STDERR $error; return 0;}
X    if(&send(&Address) !~ /^883/) {
X	$_ = &check_reply while (! /^883/);
X    }
X    return 1;
}
X
sub close_visca {
X    &check_reply while(@input_buf);
X    return 1;
}
X
sub wait {
X    # wait for completion
X    # if arg, wait for "$device-$socket"s.
X    # if no arg, wait for all device and socket
X    # return 0 on error
X    local(@wait) = @_;
X
X    # execute select once at least
X    return 0 if(! &check_reply);     # error case see $error
X    if(@wait) {
X	while(@wait) {
X	    @wait = grep(defined($busy{$_}),@wait);
X	    return 0 if(! &check_reply);     # error case see $error
X	}
X    } else {
X	while(%busy) {
X	    return 0 if(! &check_reply);     # error case see $error
X	}
X    }
X    return 1;
}
X
sub query {
X
# Do inquire
#   This call needs  arg_Inq and arg_Ans
X
X    local($cmd) = @_;
X    local($/) = "\377";
X    local($inq) = $cmd . 'Inq';
X    local($ans) = $cmd . 'Ans';
X    local($ask) = &$inq;
X    local($out) = pack("H*",$ask);
X    local($input);
X
X    if($ask =~ /error/) { print STDERR $_[0],"\n"; return ""; }
X    $input = ''; 
X    syswrite(TTY,$out,length($out));
X
X    # first busy wait for immediate reply by busy wait
X    $input .= <TTY> until ($input =~ /\377$/); 
X    return &$ans(unpack("H*",$input));
}
X
sub raw_send {
X    local ($out) = pack("H*",$_[0]);
X
X    if($_[0] =~ /error/) { print STDERR $_[0],"\n"; return ""; }
X    syswrite(TTY,$out,length($out));
}
X
sub recv {
X    # busy wait receiver
X    local($/) = "\377";
X    $input ='';
X    $input .= <TTY> until ($input =~ /\377$/); 
X    print "recv: ",unpack("H*",$input),"\n";
}
X
# back ground receiver
X
sub receiver {
X    if(! ($receiver = fork) ) {
X	$/ = "\377";
X	select(TTY); $| = 1; select(STDOUT);
X	print "Receiver start\n";
X	$input = '';  $null = '';
X	# print unpack("H*",$_) while(<TTY>);  This does not work on FNDELAY
X	while(1) {
X	    ($nfound,$timeleft) =
X		select($sout=$vin, $wout=$null, $eout=$null, undef);
X	    # sysread(TTY,$input,1);        Never blocks on FNDELAY
X	    $input .= <TTY> until ($input =~ /\377/); 
X	    print unpack("H*",$input),"\n";
X	    $input = '';
X	}
X	print "Receiver end\n";
X	exit(0);
X    }
X    1;
}
X
sub kill_receiver {
X    if($receiver) {
X	kill(9,$receiver);
X	wait;
X    }
}
X
sub debug {
X    local ($out) = @_;
X    print STDERR "$out\n";
}
X
##########################################################
# Visca Communication Part
#    Open TTY
##########################################################
X
# generated *.ph
sub TIOCGETP { 0x40067408;}
sub TIOCSETP { 0x80067409;}
sub B1200 { 0x9;}
sub B2400 { 0xb;}
sub B4800 { 0xc;}
sub B9600 { 0xd;}
sub B19200 { 0xe;}
sub B38400 { 0xf;}
sub TANDEM { 0x1;}
sub FNDELAY { 0x4;}
sub RAW { 0x20;}
sub CBREAK { 0x2;}
sub F_SETFL { 0x4;}
sub F_GETFL { 0x3;}
sub ECHO { 0x8;}
sub AF_UNIX { 0x1;}
sub SOCK_STREAM { 0x1;}
#
$dev = "/dev/cau00:/dev/cau01";        # device name, "|program" is allowed
$speed = 9600;
X
sub Init {   # No test
X  # RAW FNDELAY 9600 8bit non parity
X  $dev =~ s/([^:]+)//; $cdev = $1;
X    # Open TTY device
X    while(! open(TTY,"+<$cdev")) {
X      if ($dev =~ s/:([^:]+)//) {
X        $cdev = $1; next;
X      } else {
X         die("Can't open TTY $cdev\n");
X      }
X    } 
X    # BSD case
X    # system "stty raw tandem $speed >$dev";
X    $speed = eval "&B$speed";     # $speed must be number
X    $sgttyb_t = "ccccs";          # 4 chars and a short
X    $sgttyb = pack($sgttyb_t,(0,0,0,0,0));
X    if (ioctl(TTY,&TIOCGETP,$sgttyb)) {
X       @ary = unpack($sgttyb_t,$sgttyb);
X       $ary[0] = $ary[1] = $speed;
X       $ary[4] = &RAW;
X       $sgttyb = pack($sgttyb_t,@ary);
X       ioctl(TTY,&TIOCSETP,$sgttyb)
X        || die "Can't ioctl: $!";
X    } else { die "Can't ioctl: $!"; }
X    fcntl(TTY,&F_SETFL,&FNDELAY) || die "Can't fcntl: $!";
X    select(TTY);$|=1; 
X    select(STDOUT);$|=1; 
X
X  $sin = $vin = $win = $ein = '';
X  $null = '';
X  vec($vin,fileno(TTY),1) = 1;
}
X
sub Remote {   # No test
#   decode /etc/remote file
X
X    $REMOTE = '/etc/remote' unless $REMOTE;
X    if (-f $REMOTE) {
X	$entry = '';
X	do {
X	    $loop = "
X	    open(REMOTE,'<$REMOTE') || die \"Can't open $REMOTE\";
X	    while (<REMOTE>) {
X		next if /^#/;
X		next if /^\t/;
X		if (/(^|\\|)$NAME\[:\\|\]/) {
X		    chop;
X		    while (chop eq '\\\\') {
X			\$_ .= <REMOTE>;
X			chop;
X		    }
X		    \$_ .= ':';
X		    last;
X		}
X	    }
X	    close REMOTE;
X	    \$entry .= \$_;
X	    ";
X	    eval $loop;
X	} while s/:tc=([^:]+):/:/ && ($NAME = $1);
X	$REMOTE = $entry;
X    }
X
X    foreach $field (split(/:[\s:\\]*/,$REMOTE)) {
X	if ($field =~ /^\w\w$/) {
X	    $RM{$field} = 1;
X	}
X	elsif ($field =~ /^(\w\w)#(.*)/) {
X	    $RM{$1} = $2 if $RM{$1} eq '';
X	}
X	elsif ($field =~ /^(\w\w)=(.*)/) {
X	    $entry = $1;
X	    $_ = $2;
X	    s/\\E/\033/g;
X	    s/\\(\d\d\d)/pack('c',$1 & 0177)/eg;
X	    s/\\n/\n/g;
X	    s/\\r/\r/g;
X	    s/\\t/\t/g;
X	    s/\\b/\b/g;
X	    s/\\f/\f/g;
X	    s/\\\^/\377/g;
X	    s/\^\?/\177/g;
X	    s/\^(.)/pack('c',ord($1) & 31)/eg;
X	    s/\\(.)/$1/g;
X	    s/\377/^/g;
X	    $RM{$entry} = $_ if $RM{$entry} eq '';
X	}
X    }
X
#dv	device to use for the tty
#el	EOL marks (default is NULL)
#du	make a call flag (dial up)
#pn	phone numbers (@ =>'s search phones file; possibly taken from
#			      PHONES environment variable)
#at	ACU type
#ie	input EOF marks	(default is NULL)
#oe	output EOF string (default is NULL)
#cu	call unit (default is dv)
#br	baud rate (defaults to 300)
#fs	frame size (default is BUFSIZ) -- used in buffering writes
#	  on receive operations
#tc	to continue a capability
#
# tip9600|out96b:dv=/dev/tty01:br#9600:pa=none
X
X      $dev = $RM{dv};
X      $speed = $RM{br};
#     no parity suupport.... who use it?
}
X
##########################################################
# Visca Command Generators 
#       General  Formattor and Arguments Generator
##########################################################
X
$dest = 1;    # 8 for broadcast
$socket = 0;  # 0 or 1
X
# format
X
sub Dest { $dest = $_[0]; }
X
sub form1 {    
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "01" . $_[0] . "ff"; 
}
sub form2 {    
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "02" . $_[0] . "ff"; 
}
sub form3 {    
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "03" . $_[0] . "ff"; 
}
sub form4 {    
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "04" . $_[0] . "ff"; 
}
sub inquire {  
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "09" . $_[0] . "ff"; 
}
X
# form2 
#   Execute at Visca clock
X
sub At {
X    local($clock,$command) = @_;    #  &at(&clock,&command)
X    $_[0] =~ /error/ && return $_[0];
X    $_[1] =~ /error/ && return $_[1];
X    $command =~ s/^8.01(..)(.*)/8102$1$clock$2/;
X    return $command;
}
X
sub  Clock { 
X    local($h,$m,$s,$tick);
X    $_[0] =~ /^(..):(..):(..)\.(...)/ || return "Clock format error";
X    ($h,$m,$s,$tick) = ($1,$2,$3,$4);
X    $tick =~ s/.$//;
X    sprintf("%02d%02d%02d%02d0%1d" ,$h,$m,$s,$tick,$&); 
}
X
# form3 
#   Execute after Tape position
#     &after(&arg,&command)
X
sub After {
X    local($after,$command) = @_;
X    $_[0] =~ /error/ && return $_[0];
X    $_[1] =~ /error/ && return $_[1];
X    $command =~ s/^8.01(..)(.*)/8103$1$after$2/;
X    return $command;
}
X
# form4 
#   Execute before Tape position
#     &before(&arg,&command)
X
sub Before {
X    local($before,$command) = @_; 
X    $_[0] =~ /error/ && return $_[0];
X    $_[1] =~ /error/ && return $_[1];
X    $command =~ s/^8.01(..)(.*)/8104$1$before$2/;
X    return $command;
}
X
# Tape position
X
sub  Top {     "0101000000"; }
sub  Middle {  "0102000000"; }
sub  End {     "0103000000"; }
X
sub  Digit { 
X    local(@d) = reverse(split(//,$_[0]));
X    sprintf("11%02d%02d%02d%02d" ,$d[3],$d[2],$d[1],$d[0]); 
}
X
sub  Hms { 
X    local($h,$m,$s);
X    $_[0] =~ /^(\d+):(\d+):(\d+)/ || return "Hms format error";
X    ($h,$m,$s) = ($1,$2,$3);
X    if($h<0) { $h = -$h + 32; } 
X    sprintf("12%02d%02d%02d00" ,$h,$m,$s); 
}
sub  Time_code { 
X    local($h,$m,$s,$frame); 
X    $_[0] =~ /^(\d+):(\d+):(\d+)\.(\d+)/ || return "Time_code format error";
X    ($h,$m,$s,$frame) = ($1,$2,$3,$4);
X    sprintf("13%02d%02d%02d%02d" ,$h,$m,$s,$frame); 
}
X
# Ack and Error
#   reference
sub ack { $dest . "04" .  $socket . "ff"; }
sub completion { $dest . "05" .  $socket . "ff"; }
sub answer { $dest . "05" .  $socket . $_[0] . "ff"; }
X
%Error = (
X    "01","Message length",
X    "02","Syntax",
X    "03","Buffer full",
X    "04","Cancelled",
X    "05","No socket",
X    "40","Power off",
X    "41","Time out",
X    "42","Search",
X    "43","Condition",
X    "44","Camera mode",
X    "45","VCR mode",
X    "46","Counter type",
X    "47","Tuner",
X    "48","Emergency stop",
X    "49","No media",
X    0,0
);
X
sub Error {
X    local($_) = @_;
X    if (/^(.)06(.)(..)/) {
X	$from = $1-8; $socket = $2;  $errno = $3;
X	$from = "$from-$socket";
X	if(defined($Error{$errno})) {
X	    $error = "error from $from ".$Error{$errno};
X	    return  $error;
X	}
X    } 
X    return "error unknown reply $_";
}
X
##########################################################
#       VISCA Interface command
##########################################################
X
# Use IF_Clear for all socket cancel
sub Cancel {
X    "8" . $dest . "2" . $socket . "ff";
}
X
sub Address { "883001ff"; }
# expect  88300$nff" $n ... visca daisy chain max
X
sub Network_Change { $dest . "038ff"; }
# new commer   9038ff
X
sub IF_Clear { "8" . "8" . "010001ff"; 
X    # expect  $dest . "50ff"
X    # expect "88010001ff" when broadcast (?!)
}
X
#   &clockset(""hh:mm:ss:ttt",hh:mm:ss:ttt")
sub IF_ClockSet { "88010003" . 
X    &Clock($_[0]) .          # time set
X    &Clock($_[1]) . "ff";    # increment
}
X
sub IF_DeviceTypeInq { "8" . $dest . "090002ff"; }
sub IF_DeviceTypeAns {
X    local($_) = @_;
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    if(/^(.)050(....)(....)(....)(..)ff/) {
X	$from = $1 - 8;
X	$vendor = $2;
X	$id = $3;
X	$version = $4;
X	$max_socket = $5;
X	return 1;
X    } else { return "DeviceType syntax error" ;
X    }
}
X
sub IF_ClockInq { "8" . $dest . "090003ff"; }
sub IF_ClockAns {
X    local($_) = @_;
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    /^(.)050(..)(..)(..)(..)0(.)(..)0(.)ff/ 
X	|| return "Clock syntax error";
X    $from = $1 - 8;
X    $h = $2;
X    $m = $3;
X    $s = $4;
X    $tick = $5 . $6;
X    $tick_rate = $7 . $8;
X    return "$h:$m:$s.$tick ". $tick_rate;
}
X
##########################################################
#       Video LANC command
##########################################################
X
%MD = (
X    "On","0002",
X    "Off","0003",
X    "Stop","0100",
X    "Fast Forward","0108",
X    "Rewind","0110",
X    "Eject","0118",
X    "Still","0120",
X    "x1/10","0124",
X    "Slow","0124",
X    "x1/5","0126",
X    "Play","0128",
X    "x2","012A",
X    "Fast","012C",
X    "Locked Cue","012C",
X    "Scan","012E",
X    "Cue","012E",
X    "-1/10","0134",
X    "Reverse Slow","0134",
X    "-1/5","0136",
X    "-x2","013A",
X    "Reverse Fast","013C",
X    "Locked Review","013C",
X    "Reverse Scan","013E",
X    "Review","013E",
X    "Record Pause","0140",
X    "Record","0148",
X    "Camera Record Pause","0150",
X    "Camera Record","0158",
X    "Edit Search Forward","015C",
X    "Edit Search Reverse","015E",
X    "Frame Forward","0202",
X    "Frame Reverse","0203",
X    "Frame Record Forward","0242",
X    "Counter Reset","1001",
X    "Time Code Mode","1021",
X    "Counter Mode","1022",
X    "Voice Boost","1036",   # On/Off
X    "Main/Sub","1043",     # Audio
X    "SP/LP","1044",
X    "Input","1046",
X    "BS Monitor","1048",
X    "BS-TV/Audio","1049",
X    "TV/BS","104A",
X    "CATV/AIR","104B",
X    "Channel+","104E",
X    "Channel-","104F",
# Edit
X    "Edit Play Stanby","0520",
X    "Edit Record Stanby","0540",
# Camera Command
X    "Zoom Stop","0700",
X    "Tele","0702",
X    "Wide","0703",
X    "Focus Stop","0800",
X    "Far","0802",
X    "Near","0803",
X    "NTSC Async","220300100",
X    "NTSC Sync","220300101",
X    "NTSC CCD-F500","20300102",
X    "PAL Async","220250100",
X    "PAL Sync","220250101",
X    "",0
);
X
sub MD {
X    defined($MD{$_[0]}) || return "MD command error $_[0]";
X    &form1("02" . $MD{$_[0]});
}
X
#    top/end/digit/hms/time_code
sub MD_Search	{ &form1("0203" . $_[0]); }    
sub MD_SearchPlay	{ &form1("0203" . $_[0],"28"); }
sub MD_SearchStop	{ &form1("0203" . $_[0],"00"); }
X
sub MD_Channel	{ 
X    # &MD_Channel('BS',14)
X    local($_,@d) = ($_[0],reverse(split(//,$_[1])));
X    if(/TV/) {
X	&form1("0204" .   sprintf("%02d%02d%02d",$d[2],$d[1],$d[0]));
X    } elsif (/BS/) {
X	&form1("020410" . sprintf("%02d%02d",$d[1],$d[0]));
X    } elsif (/SCC/) {
X	&form1("020420" . sprintf("%02d%02d",$d[1],$d[0]));
X    } elsif (/JC-SAT/) {
X	&form1("020440" . sprintf("%02d%02d",$d[1],$d[0]));
X    } elsif (/NEW/) {
X	&form1("020450" . sprintf("%02d%02d",$d[1],$d[0]));
X    } elsif (/\d+/) {
X        local(@d) = reverse(split(//,$_[0]));
X	&form1("0204" . sprintf("%02d%02d%02d",$d[2],$d[1],$d[0]));
X    } else {
X	return "MD Channel error $_[0]";
X    }
}
sub MD_EditStandby	{ &form1("020520"); }
sub MD_EditPlay	{ 
X    &form2("02" . $_[0] . "28");   # &clock
}
sub MD_EditRecStandby	{ &form1("020540"); }
sub MD_EditRecord	{ 
X    &form2("02" . $_[0] . "48");   # &clock
}
X
sub MD_PowerInq	{ &inquire("0200"); }
%MD_PowerAns = (
X    "02","Power on",
X    "03","Power off"
);
X
sub MD_PowerAns {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    $_[0] =~ /^(.)050(..)ff$/ ||
X	return "Power syntax error";
X    $from = $1 - 8;  $ans = $2;
X    return $MD_PowerAns{$ans};
}
X
sub MD_Mode1Inq	{ &inquire("0201"); }
X
%MD_Mode1Ans = (
X    "00","Stop",
X    "02","Stop Tape Top",
X    "04","Stop Tape End",
X    "06","Stop Emergency",
X    "08","Fast Forward",
X    "10","Rewind",
X    "18","Eject",
X    "20","Still",
X    "24","Slow2",
X    "26","Slow1",
X    "28","Play",
X    "2a","Fast1",
X    "2c","Fast2",
X    "2e","Scan",
X    "34","Reverse Slow2",
X    "36","Reverse Slow1",
X    "38","Reverse Play",
X    "3a","Reverse Fast1",
X    "3c","Reverse Fast2",
X    "3e","Reverse Scan",
X    "40","Rec Pause",
X    "48","Record",
X    "50","Camera Rec Pause",
X    "58","Camera Rec",
X    "5c","Edit Search Forward",
X    "5e","Edit Search Reverse"
);
X
sub MD_Mode1Ans {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    $_[0] =~ /^(.)050(..)ff$/ ||
X	return "Mode1 syntax error";
X    $from = $1 - 8;  $ans = $2;
X    return $MD_Mode1Ans{$ans};
}
X
sub MD_ChannelInq	{ &inquire("0204"); }
sub MD_ChannelAns {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    $_[0] =~ /^(.)0500(.)0(.)0(.)ff$/ ||
X	return "Channel syntax error";;
X    $from = $1; 
X    return $2 . $3 . $4;
}
X
sub MD_EditControlInq	{ &inquire("020501"); }
sub MD_EditControlAns {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    $_[0] =~ /^(.)0500(.)ff$/ 
X	|| return "EditControl syntax error";
X    $from = $1 -8; 
X    return $2;
}
X
sub MD_MediaInq	{ &inquire("0212"); }
X
%MD_MediaAns = ("01","8mm","02","VHS","03","Beta",
X	    "41","Hi-8","42","S-VHS","43","ED-Beta") ;
sub MD_MediaAns {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    $_[0] =~ /^(.)050(..)(..)(..)ff$/ 
X	|| return "Meida syntax error";
X    $from = $1 -8;  $g = $2; $h = $3; $j = $4;
X
X    $ans = $MD_MediaAns{$g};
X    $ans .= " " . (($h==1 ? "SP" : "LP"));
X    $ans .= " " . (( $j & 8 ) ? "Hi-8" : "Normal");
X    $ans .= " " . (( $j & 4 ) ? "Thin" : "Thick");
X    $ans .= " " . (( $j & 2 ) ? "ME" : "MP");
X    $ans .= " " . (( $j & 1 ) ? "Playback only" : "Recordable");
X    return $ans;
}
X
%MD_InputSelectAns = ("1","Tuner","3","Line","7","Other");
sub MD_InputSelectInq	{ &inquire("0213"); }
sub MD_InputSelectAns {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X
X    $_[0] =~ /^(.)0500(.)0(.)/
X	|| return "InputSelect syntax error";;
X    $from = $1 - 8; $a = $2; $b = $3;
X    return $MD_InputSelectAns{$a} . " " . $MD_InputSelectAns{$b};
}
X
sub MD_CongigureInq	{ &inquire("0220"); }
sub MD_ConfigureAns {
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    $_[0] =~ /^(.)05(..)(..)0(.)ff$/
X	|| return "Configure syntax error";
X    $from = $1; $g = $2; $h = $3; $j = $4;
X    # $g frame / per second
X    # $h device type
X    # $j none / synchronous / CCD-F500
X    return "frame $g device $h $j";
}
X
sub MD_PositionInq		{ &inquire("020310"); }
sub MD_PositionTimecodeInq	{ &inquire("020320"); }
%MD_PositionAns = (1,"Top",2,"Middle",3,"End");
sub MD_PositionAns	{ 
X    $_[0] =~ /^.06/ && return &Error($_[0]);
X    #           9 050 12  04  14  25  00  00  39  46  17 0 9 ff
X    $_[0] =~ /^(.)050(..)(..)(..)(..)(..)(..)(..)(..)(..)0(.)ff/
X	|| return "Position syntax error";
X    $from = $1; $a = $2;  $b = $3; $c = $4; $d = $5; $e = $6;
X    $h = $7; $m = $8; $s = $9; $t = $10 . $11;
X    if($a eq "01") {
X	return 'position ' . $MD_PositionAns{$z} . " time $h:$m:$s.$t";
X    } elsif ($a eq "11") {
X	return 'counter ' . ((($b * 10 + $c)*10 + $d)*10 + $e) 
X               . " time $h:$m:$s.$t";
X    } elsif ($a eq "12") {
X	return 'hms '."$b:$c:$d"," time $h:$m:$s.$t";
X    } elsif ($a eq "21") { 
X	return 'timecde '."$b:$c:$d.$e"." time $h:$m:$s.$t";
X    } else {
X	return "Position type error";
X    }
}
X
##########################################################
# Visca 
#       Control-S command
##########################################################
X
sub Release {  &form1("0100"); }
X
# Control-S command
#   command concatenator
X
sub CntrlS {   # No test
X    local(*CMD) = @_;
X    shift(@_);
X    local($cmd,$out,$tmp,$arg);
X
X    foreach $arg (@_) {
X	defined($CMD{$arg}) || return "No Such CntrlS error $arg";
X	$tmp = $CMD{$arg};
X	if($out) {
X	    if (substr($out,0,2) ne substr($tmp,0,2)) {
X		return 
X                "Concateneate different CntrlS error $arg";
X	    }
X	    $out .= substr($tmp,2,2);
X	} else {
X	    $out = $tmp;
X	}
X    }
X    return $out;
}
X
##########################################################
#       Control-S Video ommand
##########################################################
X
$vtr = "3";
X
sub VCR_number { 
X    $vtr = $_[0]; 
}
X
%VCR = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# VCRmode1 
X    "Stop","0100",
X    "Fast Forward","0108",
X    "Rewind","0110",
X    "Eject","0118",
X    "Pause","0120",
X    "x1/10","0124",
X    "x1/5","0126",
X    "Play","0128",
X    "x2","012A",
X    "Locked Cue","012C",
X    "Fast Forward","012E",
X    "Reverse","013E",
X    "Locked Review","013C",
X    "Record","0148",
# VCRmode2 = 
X    "Frame Forward","0202",
X    "Frame Reverse","0203",
# VCRSubControl 
X    "Counter Reset","1020",
X    "Voice Boost On/Off","1036",
X    "Voice Boost","1036",
X    "Main/Sub Audio","1043",
X    "SP/LP","1044",
X    "Display On/Off","1045",
X    "Display","1045",
X    "Input Select","1046",
X    "Input","1046",
X    "Timer-Record On/Off","1047",
X    "Reserve","1047",
X    "BS Monitor","1048",
X    "BS-TV/Audio","1049",
X    "TV/BS","104A",
X    "CATV/AIR","104B",
# VCR Channel
X    "1","0401",
X    "2","0402",
X    "3","0403",
X    "4","0404",
X    "5","0405",
X    "6","0406",
X    "7","0407",
X    "8","0408",
X    "9","0409",
X    "10","040A",
X    "11","040B",
X    "10+","040B",
X    "12","040C",
X    "13","040D",
X    "14","040E",
X    "15","040F",
X    "16","0410",
X    "0","040A",
X    "1_","040D",
X    "2_","040E",
X    "Channel+","0411",
X    "Channel-","0412",
X    "TV","0460",
X    "BS","0461",
X    "SCC","0462",
X    "CS","0462",
X    "JC-SAT","0464",
X    "NEW","0465",
X    "",0
);
X
sub video { 
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "01010" . $vtr . $_[0] . "ff"; 
}
X
sub VCR {
X    &video(&CntrlS(*VCR,@_));
}
X
sub VCRTimerSet {	
X    local($_) = @_;
X    #  "Set Input 1 Channel 11 on 12/31 from 8:55 to 9:50 LP"
X    #  TV 8, BS 15, SCC 3, JSSAT 3, NEW 18
X    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
X						 localtime(time);
X    $this_month = $mon+1; $today =  $mday;
X    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
X						 localtime(time+3600*24);
X    $tomorrow_month = $mon+1; $tomorrow =  $mday;
X    if(/Input ([12])/) { 
X	$input = "0" . ($1 + 3);
X	$channel1 = 0; $channel2 = 0;
X    } elsif(/Channel (\d*)(\d)/) { 
X	$input = "01"; $channel1 = $1; $channel2 = $2;
X    } elsif(/TV\s*(\d*)(\d)/) { 
X	$input = "01"; $channel1 = $1; $channel2 = $2;
X    } elsif(/BS\s*(\d*)(\d)/) { 
X	$input = "05"; $channel1 = $1; $channel2 = $2;
X    } elsif(/SCC\s*(\d*)(\d)/) { 
X	$input = "08"; $channel1 = $1; $channel2 = $2;
X    } elsif(/JCSAT\s*(\d*)(\d)/) { 
X	$input = "09"; $channel1 = $1; $channel2 = $2;
X    } elsif(/NEW\s*(\d*)(\d)/) { 
X	$input = "0a"; $channel1 = $1; $channel2 = $2;
X    } else { return "No Input/Channel/TV/BS/SCC/JCSAT/NEW error";}
X    if(m=on (\d+)/(\d+)=) { 
X	$month = $1; $day = $2;
X    } elsif(m=today=) { 
X	$month = $this_month; $day = $today;
X    } elsif(m=tomorrow=) { 
X	$month = $tomorrow_month; $day = $tomorrow;
X    } else { return "No date error";}
X    if(/from (\d+):(\d+)/) { 
X	$begin_hour = $1; $begin_min = $2; 
X    } else { return "No from-time error";}
X    if(/to (\d+):(\d+)/) { 
X	$end_hour = $1; $end_min = $2; 
X    } else { return "No to-time error";}
X    if(/LP/) { 
X	$splp = 2;
X    } elsif(/SP/) { 
X	$splp = 1;
X    } else { return "No LP/SP mode error";}
X    if(/Set/) { 
X	$mode = 2;
X    } elsif(/Cancel/) {
X	$mode = 1;
X    } else { return "No set, No cancel error";}
X    &video(sprintf("06%s%02d0%01d%02d%02d%02d%02d%02d%02d%d%d",
X                      $input,
X                        $channel1,
X                             $channel2,
X                                 $month,
X                                     $day,
X                                         $begin_hour,
X                                             $begin_min,
X                                                 $end_hour,
X                                                     $end_min,
X                                                         $mode,
X                                                          $splp));
}
X
##########################################################
#       Control-S Monitor ommand
##########################################################
X
sub tv {
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "010110" . $_[0] . "ff"; 
}
X
%Monitor = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# Monitorchannel 
X    "1","0401",
X    "2","0402",
X    "3","0403",
X    "4","0404",
X    "5","0405",
X    "6","0406",
X    "7","0407",
X    "8","0408",
X    "9","0409",
X    "10","040A",
X    "11","040B",
X    "12","040C",
X    "13","040D",
X    "14","040E",
X    "15","040F",
X    "16","0410",
X    "10+","040B",
X    "0","040A",
X    "1_","040D",
X    "2_","040E",
X    "Channel+","0411",
X    "Channel-","0412",
X    "TV","0460",
X    "BS","0461",
X    "SCC","0462",
X    "CS","0462",
X    "JC-SAT","0464",
X    "NEW","0465",
# MonitorSubControl 
X    "Select Tuner","1010",
X    "TV","101F",
X    "Video1","1011",
X    "Video2","1012",
X    "Video3","1013",
X    "RGB1","1014",
X    "Analog RGB1","1014",
X    "RGB2","1015",
X    "Analog RGB2","1015",
X    "Digital RGB1","1016",
X    "Digital RGB2","1017",
X    "Video4","1018",
X    "Video5","1019",
X    "Video6","101A",
X    "HD1","101B",
X    "HD2","101C",
X    "HD3","101D",
X    "Picture+","1020",
X    "Picture-","102Y",
X    "Color+","1022",
X    "Color-","1023",
X    "Hue+","1028",
X    "Hue-","1029",
X    "Sharp+","102A",
X    "Sharp-","102B",
X    "Volume+","1032",
X    "Volume-","1033",
X    "Mute","1035",
X    "Main/Sub","1043",
X    "Display","1045",  # On/Off
X    "Input","1046",
X    "BS-TV/Audio","1049",
X    "CATV/AIR","104B",
X    "",0
);
X
sub Monitor {
X    &tv(&CntrlS(*Monitor,@_));
}
X
##########################################################
#       Control-S AV Selector ommand
##########################################################
X
sub av {
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "010114" . $_[0] . "ff"; 
}
X
%AV = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# Monitor Select
X    "Monitor1 Input/Output","0110",
X    "Monitor1 1","0111",
X    "Monitor1 2","0112",
X    "Monitor1 3","0113",
X    "Monitor1 4","0114",
X    "Monitor1 5","0115",
X    "Monitor1 6","0116",
X    "Monitor2 Input/Output","0120",
X    "Monitor2 1","0121",
X    "Monitor2 2","0122",
X    "Monitor2 3","0123",
X    "Monitor2 4","0124",
X    "Monitor2 5","0125",
X    "Monitor2 6","0126",
# VAIOSelect 
X    "Matrix Select 1","0201",
X    "Matrix Select 2","0202",
X    "Matrix Select 3","0203",
X    "Matrix Select 4","0204",
X    "Matrix Select 5","0205",
X    "Matrix Select 6","0206",
X    "Matrix","0211",
X    "S-Video","0212",
X    "Aux Audio","0213",
X    "AV Processor","0214",
X    "AV Processor Pass-V","0221",
X    "AV Processor Pass-A","0222",
X    "Mode-C V/A","0223",  # toggle
X    "Line 6 Front/Rear","0224",
X    "Clear","0225",
X    "Memory Set","0230",
X    "M1","0231",
X    "M2","0232",
X    "M3","0233",
X    "M4","0234",
# VAIOSelect
X    "Mode Lock","1001",  # On/Off
X    "Cancel","1002",
X    "Volume-","1032",
X    "Volume+","1033",
X    "Video Mute","1034",
X    "Audio Mute","1035",
X    "Toggle Audio Mode","1043",
X    "",0
);
X
sub AV {
X    &av(&CntrlS(*AV,@_));
}
X
##########################################################
#       Control-S Projector ommand
##########################################################
X
sub proj {
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "010115" . $_[0] . "ff"; 
}
X
%Projector = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# Sub Control
X    "Picture Reset","1001",
X    "Select Video","1010",
X    "Slot A","1011",
X    "Slot B","1012",
X    "Picture+","1020",
X    "Picture-","1021",
X    "Color+","1022",
X    "Color-","1023",
X    "Brightness+","1026",
X    "Brightness-","1027",
X    "Hue+","1028",
X    "Hue-","1029",
X    "Sharp+","102A",
X    "Sharp-","102B",
X    "Volume+","1032",
X    "Volume-","1033",
X    "Video Mute","1034",
X    "Audio Mute","1035",
X    "Display On","1048",
X    "Display Off","1049",
X    "Secam","104A",  # On/Off
X    "Clear Blue","104B",
X    "Page","104C",
X    "Memory","104D",
X    "Operate >","1050",
X    "Operate <","1051",
X    "Operate ^","1052",
X    "Operate v","1053",
X    "RGB-size","1058",
X    "RGB-shift","1059",
X    "R-cent","105A",
X    "RBcent","105C",
# ProjectorDeviceSelect 
X    "Device 1","1001",
X    "Device 2","1002",
X    "Device 3","1003",
X    "Device 4","1004",
X    "Device 5","1005",
X    "Device 6","1006",
X    "Device 7","1007",
X    "Device 8","1008",
X    "Device 9","1009",
X    "Device Enter","100C",
# ProjectorInputSelect 
X    "Video","1303",
X    "Input A","1304",
X    "Input B","1305",
X    "Switcher1-1","1311",
X    "Switcher1-2","1312",
X    "Switcher1-3","1313",
X    "Switcher1-4","1314",
X    "Switcher1-5","1315",
X    "Switcher1-6","1316",
X    "Switcher1-7","1317",
X    "Switcher1-8","1318",
X    "Switcher2-1","1321",
X    "Switcher2-2","1322",
X    "Switcher2-3","1323",
X    "Switcher2-4","1324",
X    "Switcher2-5","1325",
X    "Switcher2-6","1326",
X    "Switcher2-7","1327",
X    "Switcher2-8","1328",
X    "",0
);
X
sub Projector {	
X    &proj(&CntrlS(*Projector,@_));
}
X
##########################################################
#       Control-S Multi Disc Player Command
##########################################################
X
sub mdp {
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "010104" . $_[0] . "ff"; 
}
X
%MDP = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# mode 1
X    "Stop","0100",
X    "Open/Close","0118",
X    "Still","0120",
X    "+Step Slow","0124",
X    "+1/2","0126",
X    "Play","0128",
X    "+x2","012A",
X    "+x5","012C",
X    "Slow Search","012D",
X    "Repeated Search","012E",
X    "-Step Slow","0134",
X    "-1/2","0136",
X    "Reverse","0138",
X    "-x2","013A",
X    "-x5","013C",
X    "Slow Reverse Search","013D",
X    "Repeated Reverse Search","013E",
X    "Side A","0160",
X    "Side B","0161",
X    "Multi Speed >","0162",
X    "Multi Speed <","0163",
X    "Speed+","0164",
X    "Speed-","0165",
# Mode2
X    "Forward Step","0202",
X    "Reverse Step","0203",
# Search
X    "Clear","0300",
X    "1","0301",
X    "2","0302",
X    "3","0303",
X    "4","0304",
X    "5","0305",
X    "6","0306",
X    "7","0307",
X    "8","0308",
X    "9","0309",
X    "0","030A",
X    "Chapter","030B",
X    "Enter","030C",
X    "Search","030C",
X    "Frame","030D",
X    "Time","030D",
X    "+10","030E",
X    "Forward Chapter","0311",
X    "Reverse Chapter","0312",
# Sub Control
X    "Sub Clear","1001",
X    "Main","1041",
X    "L","1041",
X    "Sub","1042",
X    "R","1042",
X    "L/R","1043",
X    "Main/Sub","1043",
X    "Display","1045",   # On Off
X    "",0
);
X
sub MDP {
X    &mdp(&CntrlS(*MDP,@_));
}
X
##########################################################
#       Control-S TV/BS Tuner Command
##########################################################
X
sub tuner {
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "010116" . $_[0] . "ff"; 
}
X
%Tuner = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# Channel 
X    "1","0401",
X    "2","0402",
X    "3","0403",
X    "4","0404",
X    "5","0405",
X    "6","0406",
X    "7","0407",
X    "8","0408",
X    "9","0409",
X    "10","040A",
X    "11","040B",
X    "12","040C",
X    "Enter","040C",
X    "13","040D",
X    "14","040E",
X    "15","040F",
X    "16","0410",
X    "10+","0413",
X    "0","040A",
X    "1_","040C",
X    "2_","040D",
X    "Channel+","0411",
X    "Channel-","0412",
X    "Channel Lock","0450",
X    "Channel Lock On","0452",
X    "Channel Lock Off","0453",
X    "TV","0460",
X    "BS","0461",
X    "SCC","0462",
X    "SCC A","0462",
X    "SCC B","0463",
X    "CS","0462",
X    "JC-SAT","0464",
X    "JC-SAT 1","0464",
X    "JC-SAT 2","0465",
X    "JC-SAT 3","0466",
X    "NEW","0465",
X    "SAT JAPAN 1","0467",
X    "SAT JAPAN 1","0468",
# Tuner SubControl 
X    "Video Reset","101F",
X    "Main/Sub","1043",
X    "Display","1045",  # On/Off
X    "Input","1046",
X    "IF Input","104C",  # Toggle
X    "Satellite","104D",  # Toggle
X    "Main/Sub Audio","1053",
X    "BS-TV/Audio","1059",
X    "Output Inside","105A",
X    "Output Outside","105B",
X    "Output In/Out","105C",
X    "",0
);
X
sub Tuner {
X    &tuner(&CntrlS(*Tuner,@_));
}
X
##########################################################
#       Control-S Muse Decoder Command
##########################################################
X
sub muse {
X    $_[0] =~ /error/ && return $_[0];
X    "8" . $dest . "010117" . $_[0] . "ff"; 
}
X
%Muse = (
X    "On","0002",
X    "Off","0003",
X    "On/Off","0010",
# Channel 
X    "1","0401",
X    "2","0402",
X    "3","0403",
X    "4","0404",
X    "5","0405",
X    "6","0406",
X    "7","0407",
X    "8","0408",
X    "9","0409",
X    "10","040A",
X    "11","040B",
X    "12","040C",
X    "Enter","040C",
X    "13","040D",
X    "14","040E",
X    "15","040F",
X    "16","0410",
X    "Channel+","0411",
X    "Channel-","0412",
# Muse SubControl 
X    "Video Reset","101F",
X    "Video 1","1011",
X    "Main/Sub","1043",
X    "Display","1045",  # On/Off
X    "Input","1046",
X    "BS-TV/Audio","1049",
X    "",0
);
X
sub Muse {
X    &muse(&CntrlS(*Muse,@_));
}
X
##########################################################
#   Visca.pl Command list / Test Generators
##########################################################
X
# &list;      	        # see Visca command
# &test_generator;      # generate test script
X
sub list {
X    open(S,"<$source");
X    $sub = '';
X    while(<S>) {
X	if(/^######/) {
X	    if($sub) { print "\&$sub;\n"; $sub = '';}
X	    print; 
X	    while(<S>) {
X		print;
X		last if(/^#####/);
X	    }
X	    next;
X	}
X	if(/^sub\s+([A-Z]\w*)\s*{/) {
X	    next if (/No test/);
X	    if($sub) { 
X    		if(defined($test_arg{$sub})) {
X		    print "\&$sub(",$test_arg{$sub},");\n"; 
X		} else {
X		    print "\&$sub;\n"; 
X		}
X	    }
X	    $sub = $1;
X	}
X	if(/\$(\w+)\{\$\_\[0\]\}/ || /CntrlS\(\*(\w+),\@\_\)/) {
X	    /defined/ && next;
X	    $sub || next;
X	    eval "\@keys = sort keys \%$1";
X	    foreach $key (@keys) {
X		next if ($key eq "");
X		print "\&$sub\(\'",$key,"\'\);\n";
X	    }
X	    $sub = '';
X	}
X    }
X    if($sub) { print "\&$sub;\n"; }
}
X
%test_arg = (
X    "Dest","1",
X    "At",'&Clock("04:55:66.123"),&MD("Play")',
X    "Clock",'"04:55:66.123"',
X    "After",'&Top,&MD("Play")',
X    "Before",'&Hms("04:55:66"),&MD("Play")',
X    "Digit","5321",
X    "Hms",'"1:22:33"',
X    "Time_code",'"1:22:30.20"',
X    "Error",'"906044ff"',
X    "IF_ClockSet",'"04:55:66.123","00:00:01.100"',
X    "IF_DeviceTypeAns",'"905000010102010102ff"',
X    "IF_ClockAns",'"905000002907013000ff"',
X    "MD_PowerAns",'"905002ff"',
X    "MD_Mode1Ans",'"90502eff"',
X    "MD_Channel",'"12"',
X    "MD_ChannelAns",'"906047ff"',
X    "MD_EditControlAns",'"905001ff"',
X    "MD_MediaAns",'"9050010100ff"',
X    "MD_InputSelectAns",'"90500303ff"',
X    "MD_CongigureAns",'"9050300100ff"',
X    "MD_PositionAns",'"905012041425000039461709ff"',
X    "MD_Search",'&Hms("04:35:00")',
X    "MD_SearchPlay",'&Hms("04:35:00")',
X    "MD_SearchStop",'&Hms("04:35:00")',
X    "VCR_number",'2',
X    "VCRTimerSet",'"Set Input 1 Channel 11 on 12/31 from 8:55 to 9:50 LP"',
X    0,0
);
X
sub test_call {
X    local($cmd,$arg) = @_; 
X    if(defined($test_arg{$cmd})) {
X	$arg = $test_arg{$cmd}; $arg =~ s/(\W)/\\$1/g;
X	print 'printf "%-40s", "\\&',$cmd,'(',$arg,')=";';
X	print  'print &',$cmd,'(',$test_arg{$cmd},'),"\\n";',"\n";
X    } elsif($arg) {
X	$arg0 = $arg; $arg0 =~ s/(\W)/\\$1/g;
X	print 'printf "%-40s", "\\&',$cmd,'(',$arg0,')=";';
X	print  'print &',$cmd,'(',$arg,'),"\\n";',"\n";
X    } else {
X	print 'printf "%-40s", "\\&',$cmd,'=";';
X	print  'print &',$cmd,',"\\n";',"\n";
X    }
}
X
sub test_generator {
X    open(S,"<$source");
X    $sub = '';
X    print "require \"visca.pl\";\n";
X    print "package Visca;\n";
X
X    while(<S>) {
X	if(/^######/) {
X	    if($sub) { &test_call($sub); $sub='';}
X	    print 'print "',$_,'";',"\n";
X	    while(<S>) {
X		print 'print "',$_,'";',"\n";
X		last if(/^#####/);
X	    }
X	    next;
X	}
X	if(/^sub\s+([A-Z]\w*)\s*{/) {
X	    next if (/No test/);
X	    if($sub) { &test_call($sub)}
X	    $sub = $1;
X	}
X	if( /CntrlS\(\*(\w+),\@\_\)/) {
X	    /defined/ && next;
X	    $sub || next;
X	    eval "\@keys = sort keys \%$1";
X	    $prev = '';
X	    foreach $key (@keys) {
X		next if ($key eq "");
X		&test_call($sub,'"'.$key.'"');
#		if($prev) { &test_call($sub,'"'.$key.'","'.$prev.'"'); }
X		$prev = $key;
X	    }
X	    $sub = '';
X	} elsif(/\$(\w+)\{\$\_\[0\]\}/) {
X	    /defined/ && next;
X	    $sub || next;
X	    eval "\@keys = sort keys \%$1";
X	    foreach $key (@keys) {
X		next if ($key eq "");
X		&test_call($sub , '"'.$key.'"');
X	    }
X	    $sub = '';
X	}
X    }
X    if($sub) { &test_call($sub)}
}
X
1;
# end
SHAR_EOF
  $shar_touch -am 0117002896 'visca.pl' &&
  chmod 0644 'visca.pl' ||
  echo 'restore of visca.pl failed'
  shar_count="`wc -c < 'visca.pl'`"
  test 36062 -eq "$shar_count" ||
    echo "visca.pl: original size 36062, current size $shar_count"
fi
# ============= visca.man ==============
if test -f 'visca.man' && test X"$1" != X"-c"; then
  echo 'x - skipping visca.man (file already exists)'
else
  echo 'x - extracting visca.man (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'visca.man' &&
##########################################################
# Visca Communication Part
#    LANC Command Handshake
#	    Tue Jan 16 20:19:01 JST 1996
##########################################################
X
1. Visca introduction
X
Visca is an interface protocol damong Video / TV products supported by Sony.
This is a Perl library of Visca interface. Basic connection of
Visca and Computer is shown below.
X
X  -----------+   +--------+  Control-S
X             |   |        +------------------------+  TV MDP  etc
X      RS232C +---+VBOX-II | 
X (Unix TTY)  |   |        +------------------------+  VCR
X  -----------+   +--------+  Control-L(Lanc Out)  
X
Control-S is basically similar interface of IR commandar. Contorol-L/ 
LANC inteface is more sophisticated bi-dirctional interface but only 
supported by VCR. 
X
VBOX-II can be daisy chained and controled by one RS232C line.
This library supports daisy chained VBOX but no supports for
multiple RS232C line.
X
X  -----------+   +--------+     +--------+
X             |   |        |     |        |
X      RS232C +---+VBOX-II +-----+VBOX-II +-------> 
X (Unix TTY)  |   |        +--+  |        +--+
X  -----------+   +--------+  |  +--------+  | 
X                           VCR1            VCR2
X
The topology of the Visca is ring. 
X
One VBOX-II control one LANC and one Control-S. Control-S can be
cascaded by Constrol-S-in and Control-S-out. This means if you
want to do precise edit, you need two VBOXes and two LANC VCRs.
X
Known traps;
X
In some VCR, there are master/slave mode of LANC. Use slave mode.
Some Monitor has a Control-S disable switch.
Some VCR cannot be powered on by Control-S or LANC.
X
2. Visca protocol command
X
&open_visca
&close_visca
X
Open or close Visca interface. It opens TTY device $dev device with $speed.
$dev and $speed must be set before the call. &Remote is a decoder
of /etc/remote file. &Remote('out96b') search an entry out96b
from /etc/remote and set $dev and $speed. &open_visca then run
IF_Clear and Address command. Address command needs 10 or 20 seconds
to complete.
X
To specify VBOX destination, use
X    &Dest($dest).
To specify VCR Control-S number (VTR1,VTR2,VTR3)  destination, use
X    &VCR_number($number).
X
Visca protocol has two type of acknowledge;
X    Acknowledge for visca command
X    Acknowledge for command completion
In case of a Control-S or some of Lanc command returns completion
immediately but some of Lanc commands needs longer (>30sec) to
complete. For examle, Search or Power-On may require longer time.
X
&send(Command)
&send(Command,CheckTime)
X
This first sends Visca command then do busy wait for immediate acknowledge
of visca command. Then it checks immediate reply in $check_time second.
The checktime can be overwrite by the second argument. Command is hex 
encoded binary, and it is generated by this library. The device become
busy until completion. 
X
Each VBox has 2 buffers for busy command. If you send one
command when there are two busy command, it generates
"buffer full" error. Busy state is kept in %busy associative
array using "$dest-$socket" key.
X
&wait
&wait("$dest-$socket")
X
wait for Visca command completion. If there are no busy command
(! %busy), it returns immediately. Second form wait for particular
busy command.
X
Lanc command is bi-directional unlike Control-S. 
X
X
&query(Command)
X
returns answer of the query command as a string.
X
Example:
X
X    #!/usr/local/bin/perl
X    require "visca.pl";          # need this library
X    package Visca;               # in Visca package
X
X    $dev = '/dev/tty00'; $speed = 9600;     # set device and speed
X
X    sub sendp { print &send(@_),"\n"; }
X    sub queryp { print &query(@_),"\n"; }
X
X    print &open_visca,"\n";   # Init, IF_Clear, Address
X
X    &Dest(1); &VCR_number(3);    # first VBOX and VTR3
X
X    print "VCR power on\n";
X    &sendp(&VCR('On'));          # Power on VTR3 by Control-S
X
X    sleep(1);
X
X    print "power on\n";
X    &sendp(&MD('On'));           # Power on Control-L device
X    print "Inquire Meida\n";
X    &queryp('MD_Media');         # Lanc command query
X    print "search\n";
X
X    &sendp(&MD_Search(&Hms('04:30:00')));   # Send Search Command
X	print join(" ",%busy),"\n";         # Check busy state
X    print "play\n";                         # Use second socket
X    &sendp(&MD('Play'));
X	print join(" ",%busy),"\n";
X    &wait;                                  # wait command completion
X    print "stop\n";
X    &sendp(&MD('Stop'));                    # then stop
X    print &close_visca,"\n";                # wait for completion
X
X
3. Visca LANC command generator
X
##########################################################
# Visca Command Generators 
#       General  Formattor and Arguments Generator
##########################################################
X
&Dest(1);
X
Set destination 1
X
&At(&Clock("04:55:66.123"),&MD("Play"));
X
Execute at Visca internal clock. 
X
&After(&Top,&MD("Play"));
&Before(&Hms("04:55:66"),&MD("Play"));
X
Execute just after or just before the tape position. The tape position
can be specified by top or end,
X    &Top &End
tape coounter,
X    &Digit(5321)
linear time counter,
X    &Hms("1:22:33")
and time code,
X    &Time_code("1:22:30.20")
X
##########################################################
#       VISCA Error code
##########################################################
X
Error code can be decoded into ascii form by
X    &Error(Error).
X
##########################################################
#       VISCA Interface command
##########################################################
X
&Cancel;
X    Cancel previous command
&Address;
X    Set daisey chain address. Address command is returned.
&Network_Change;
X    Network change notification
&IF_Clear;
X    Reset Visca, cancel all command
&IF_ClockSet("04:55:66.123","00:00:01.100");
X    Set Visca internal clock and clock interval. (Not used) 
X
&query(&IF_DeviceType)
X    Retrun Visca device type.
&query(&IF_Clock)
X    Query Visca internal clock.
X
##########################################################
#       Video LANC command
##########################################################
X
LANC  (3p mini-mini plug, or 5 pin DIN) inteface. Video command only.
X
X    Basic Play
&MD('Off');
&MD('On');
&MD('Play');
&MD('Stop');
&MD('Record');
&MD('Rewind');
&MD('Eject');
&MD('Fast Forward');
&MD('Record Pause');
&MD('Reverse Fast');
&MD('Reverse Scan');
&MD('Reverse Slow');
&MD('Review');
&MD('Scan');
&MD('Slow');
&MD('Still');
&MD('-1/10');
&MD('-1/5');
&MD('-x2');
&MD('x1/10');
&MD('x1/5');
&MD('x2');
&MD('Cue');
&MD('Fast');
&MD('Locked Cue');
&MD('Locked Review');
&MD('Frame Forward');
&MD('Frame Record Forward');
&MD('Frame Reverse');
X    Input Select
&MD('BS Monitor');
&MD('BS-TV/Audio');
&MD('CATV/AIR');
&MD('TV/BS');
&MD('Input');
X    Channel
&MD('Channel+');
&MD('Channel-');
&MD_Channel("12");
X    Camera Command
&MD('Camera Record');
&MD('Camera Record Pause');
&MD('Far');
&MD('Near');
&MD('Focus Stop');
&MD('Tele');
&MD('Wide');
&MD('Zoom Stop');
X    Mode
&MD('SP/LP');
&MD('Main/Sub');
&MD('Voice Boost');
&MD('Counter Mode');
&MD('Time Code Mode');
&MD('Counter Reset');
&MD('NTSC Async');
&MD('NTSC CCD-F500');
&MD('NTSC Sync');
&MD('PAL Async');
&MD('PAL Sync');
X    Edit
&MD('Edit Play Stanby');
&MD('Edit Record Stanby');
&MD('Edit Search Forward');
&MD('Edit Search Reverse');
&MD_EditStandby;
&MD_EditPlay;
&MD_EditRecStandby;
&MD_EditRecord;
X    Search
&MD_Search(&Hms("04:35:00"));
&MD_SearchPlay(&Hms("04:35:00"));
&MD_SearchStop(&Hms("04:35:00"));
X
X    Queries, return an ascii string
X
&query(&MD_Power)
&query(&MD_Mode1)
&query(&MD_Channel)
&query(&MD_EditControl)
&query(&MD_Media)
&query(&MD_InputSelect)
&query(&MD_Congigure)
&query(&MD_Position)
&query(&MD_PositionTimecode)
X
##########################################################
# Visca Control-S command
##########################################################
X
Constol-S (mini plug) is IR remote command. It can be
concatenetaed like &VCR('CS','1','8').
Some of the command keeps pushed state.
This is canceled by Release command.
X
&Release;
X
There is no query in Control-S command. It returns immediate
acknowledge and completion. 
X
##########################################################
#       Control-S Video command
##########################################################
X
X    Set VCR number
X
&VCR_number(2);
X
X    Channel 
X    for 18ch, use &VCR('CS','1','8')
X
&VCR('0');
&VCR('1');
&VCR('1_');
&VCR('2');
&VCR('2_');
&VCR('3');
&VCR('4');
&VCR('5');
&VCR('6');
&VCR('7');
&VCR('8');
&VCR('9');
&VCR('10');
&VCR('10+');
&VCR('11');
&VCR('12');
&VCR('13');
&VCR('14');
&VCR('15');
&VCR('16');
&VCR('BS');
&VCR('CS');
&VCR('CATV/AIR');
&VCR('JC-SAT');
&VCR('NEW');
&VCR('SCC');
&VCR('TV');
&VCR('TV/BS');
&VCR('Channel+');
&VCR('Channel-');
&VCR('BS Monitor');
&VCR('BS-TV/Audio');
&VCR('Main/Sub Audio');
X
X    Input Select
X
&VCR('Input');
&VCR('Input Select');
X
X    Counter mode
X
&VCR('Counter Reset');
&VCR('Display');
&VCR('Display On/Off');
X
X    Basic Play
X
&VCR('Eject');
&VCR('Fast Forward');
&VCR('Frame Forward');
&VCR('Frame Reverse');
&VCR('Locked Cue');
&VCR('Locked Review');
&VCR('Off');
&VCR('On');
&VCR('On/Off');
&VCR('Pause');
&VCR('Play');
&VCR('Record');
&VCR('Reserve');
&VCR('Reverse');
&VCR('Rewind');
&VCR('SP/LP');
&VCR('Stop');
&VCR('x1/10');
&VCR('x1/5');
&VCR('x2');
X
X    Misc
X
&VCR('Timer-Record On/Off');
&VCR('Voice Boost');
&VCR('Voice Boost On/Off');
&VCRTimerSet;
X
X
##########################################################
#       Control-S Monitor command
##########################################################
&Monitor('0');
&Monitor('1');
&Monitor('2');
&Monitor('3');
&Monitor('4');
&Monitor('5');
&Monitor('6');
&Monitor('7');
&Monitor('8');
&Monitor('9');
&Monitor('10');
&Monitor('10+');
&Monitor('11');
&Monitor('12');
&Monitor('13');
&Monitor('14');
&Monitor('15');
&Monitor('16');
&Monitor('1_');
&Monitor('2_');
&Monitor('Analog RGB1');
&Monitor('Analog RGB2');
&Monitor('BS');
&Monitor('BS-TV/Audio');
&Monitor('CATV/AIR');
&Monitor('CS');
&Monitor('Channel+');
&Monitor('Channel-');
&Monitor('Color+');
&Monitor('Color-');
&Monitor('Digital RGB1');
&Monitor('Digital RGB2');
&Monitor('Display');
&Monitor('HD1');
&Monitor('HD2');
&Monitor('HD3');
&Monitor('Hue+');
&Monitor('Hue-');
&Monitor('Input');
&Monitor('JC-SAT');
&Monitor('Main/Sub');
&Monitor('Mute');
&Monitor('NEW');
&Monitor('Off');
&Monitor('On');
&Monitor('On/Off');
&Monitor('Picture+');
&Monitor('Picture-');
&Monitor('RGB1');
&Monitor('RGB2');
&Monitor('SCC');
&Monitor('Select Tuner');
&Monitor('Sharp+');
&Monitor('Sharp-');
&Monitor('TV');
&Monitor('Video1');
&Monitor('Video2');
&Monitor('Video3');
&Monitor('Video4');
&Monitor('Video5');
&Monitor('Video6');
&Monitor('Volume+');
&Monitor('Volume-');
X
##########################################################
#       Control-S AV Selector command
##########################################################
&AV('AV Processor');
&AV('AV Processor Pass-A');
&AV('AV Processor Pass-V');
&AV('Audio Mute');
&AV('Aux Audio');
&AV('Cancel');
&AV('Clear');
&AV('Line 6 Front/Rear');
&AV('M1');
&AV('M2');
&AV('M3');
&AV('M4');
&AV('Matrix');
&AV('Matrix Select 1');
&AV('Matrix Select 2');
&AV('Matrix Select 3');
&AV('Matrix Select 4');
&AV('Matrix Select 5');
&AV('Matrix Select 6');
&AV('Memory Set');
&AV('Mode Lock');
&AV('Mode-C V/A');
&AV('Monitor1 1');
&AV('Monitor1 2');
&AV('Monitor1 3');
&AV('Monitor1 4');
&AV('Monitor1 5');
&AV('Monitor1 6');
&AV('Monitor1 Input/Output');
&AV('Monitor2 1');
&AV('Monitor2 2');
&AV('Monitor2 3');
&AV('Monitor2 4');
&AV('Monitor2 5');
&AV('Monitor2 6');
&AV('Monitor2 Input/Output');
&AV('Off');
&AV('On');
&AV('On/Off');
&AV('S-Video');
&AV('Toggle Audio Mode');
&AV('Video Mute');
&AV('Volume+');
&AV('Volume-');
##########################################################
#       Control-S Projector command
##########################################################
&Projector('Audio Mute');
&Projector('Brightness+');
&Projector('Brightness-');
&Projector('Clear Blue');
&Projector('Color+');
&Projector('Color-');
&Projector('Device 1');
&Projector('Device 2');
&Projector('Device 3');
&Projector('Device 4');
&Projector('Device 5');
&Projector('Device 6');
&Projector('Device 7');
&Projector('Device 8');
&Projector('Device 9');
&Projector('Device Enter');
&Projector('Display Off');
&Projector('Display On');
&Projector('Hue+');
&Projector('Hue-');
&Projector('Input A');
&Projector('Input B');
&Projector('Memory');
&Projector('Off');
&Projector('On');
&Projector('On/Off');
&Projector('Operate <');
&Projector('Operate >');
&Projector('Operate ^');
&Projector('Operate v');
&Projector('Page');
&Projector('Picture Reset');
&Projector('Picture+');
&Projector('Picture-');
&Projector('R-cent');
&Projector('RBcent');
&Projector('RGB-shift');
&Projector('RGB-size');
&Projector('Secam');
&Projector('Select Video');
&Projector('Sharp+');
&Projector('Sharp-');
&Projector('Slot A');
&Projector('Slot B');
&Projector('Switcher1-1');
&Projector('Switcher1-2');
&Projector('Switcher1-3');
&Projector('Switcher1-4');
&Projector('Switcher1-5');
&Projector('Switcher1-6');
&Projector('Switcher1-7');
&Projector('Switcher1-8');
&Projector('Switcher2-1');
&Projector('Switcher2-2');
&Projector('Switcher2-3');
&Projector('Switcher2-4');
&Projector('Switcher2-5');
&Projector('Switcher2-6');
&Projector('Switcher2-7');
&Projector('Switcher2-8');
&Projector('Video');
&Projector('Video Mute');
&Projector('Volume+');
&Projector('Volume-');
##########################################################
#       Control-S Multi Disc Player Command
##########################################################
&MDP('+1/2');
&MDP('+10');
&MDP('+Step Slow');
&MDP('+x2');
&MDP('+x5');
&MDP('-1/2');
&MDP('-Step Slow');
&MDP('-x2');
&MDP('-x5');
&MDP('0');
&MDP('1');
&MDP('2');
&MDP('3');
&MDP('4');
&MDP('5');
&MDP('6');
&MDP('7');
&MDP('8');
&MDP('9');
&MDP('Chapter');
&MDP('Clear');
&MDP('Display');
&MDP('Enter');
&MDP('Forward Chapter');
&MDP('Forward Step');
&MDP('Frame');
&MDP('L');
&MDP('L/R');
&MDP('Main');
&MDP('Main/Sub');
&MDP('Multi Speed <');
&MDP('Multi Speed >');
&MDP('Off');
&MDP('On');
&MDP('On/Off');
&MDP('Open/Close');
&MDP('Play');
&MDP('R');
&MDP('Repeated Reverse Search');
&MDP('Repeated Search');
&MDP('Reverse');
&MDP('Reverse Chapter');
&MDP('Reverse Step');
&MDP('Search');
&MDP('Side A');
&MDP('Side B');
&MDP('Slow Reverse Search');
&MDP('Slow Search');
&MDP('Speed+');
&MDP('Speed-');
&MDP('Still');
&MDP('Stop');
&MDP('Sub');
&MDP('Sub Clear');
&MDP('Time');
##########################################################
#       Control-S TV/BS Tuner Command
##########################################################
&Tuner('0');
&Tuner('1');
&Tuner('2');
&Tuner('3');
&Tuner('4');
&Tuner('5');
&Tuner('6');
&Tuner('7');
&Tuner('8');
&Tuner('9');
&Tuner('10');
&Tuner('10+');
&Tuner('11');
&Tuner('12');
&Tuner('13');
&Tuner('14');
&Tuner('15');
&Tuner('16');
&Tuner('1_');
&Tuner('2_');
&Tuner('BS');
&Tuner('BS-TV/Audio');
&Tuner('CS');
&Tuner('Channel Lock');
&Tuner('Channel Lock Off');
&Tuner('Channel Lock On');
&Tuner('Channel+');
&Tuner('Channel-');
&Tuner('Display');
&Tuner('Enter');
&Tuner('IF Input');
&Tuner('Input');
&Tuner('JC-SAT');
&Tuner('JC-SAT 1');
&Tuner('JC-SAT 2');
&Tuner('JC-SAT 3');
&Tuner('Main/Sub');
&Tuner('Main/Sub Audio');
&Tuner('NEW');
&Tuner('Off');
&Tuner('On');
&Tuner('On/Off');
&Tuner('Output In/Out');
&Tuner('Output Inside');
&Tuner('Output Outside');
&Tuner('SAT JAPAN 1');
&Tuner('SCC');
&Tuner('SCC A');
&Tuner('SCC B');
&Tuner('Satellite');
&Tuner('TV');
&Tuner('Video Reset');
##########################################################
#       Control-S Muse Decoder Command
##########################################################
&Muse('1');
&Muse('2');
&Muse('3');
&Muse('4');
&Muse('5');
&Muse('6');
&Muse('7');
&Muse('8');
&Muse('9');
&Muse('10');
&Muse('11');
&Muse('12');
&Muse('13');
&Muse('14');
&Muse('15');
&Muse('16');
&Muse('BS-TV/Audio');
&Muse('Channel+');
&Muse('Channel-');
&Muse('Display');
&Muse('Enter');
&Muse('Input');
&Muse('Main/Sub');
&Muse('Off');
&Muse('On');
&Muse('On/Off');
&Muse('Video 1');
&Muse('Video Reset');
X
##########################################################
#   Visca.pl Command list / Test Generators
##########################################################
X
&list
&test_generator
X
# end
SHAR_EOF
  $shar_touch -am 0116201996 'visca.man' &&
  chmod 0644 'visca.man' ||
  echo 'restore of visca.man failed'
  shar_count="`wc -c < 'visca.man'`"
  test 16318 -eq "$shar_count" ||
    echo "visca.man: original size 16318, current size $shar_count"
fi
# ============= examples/md_off.pl ==============
if test ! -d 'examples'; then
  echo 'x - creating directory examples'
  mkdir 'examples'
fi
if test -f 'examples/md_off.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/md_off.pl (file already exists)'
else
  echo 'x - extracting examples/md_off.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/md_off.pl' &&
#!/usr/local/bin/perl
X
require "/usr/user/kono/src/vbox/visca.pl";
X
package Visca;
X
$dev = '/dev/tty00'; $speed = 9600;
X
&open_visca;
&Dest(1); &VCR_number(3);
X
&send(&MD('Stop')); 
&wait;
sleep 5;
&send(&VCR('Off')); 
X
# end
SHAR_EOF
  $shar_touch -am 0107014996 'examples/md_off.pl' &&
  chmod 0755 'examples/md_off.pl' ||
  echo 'restore of examples/md_off.pl failed'
  shar_count="`wc -c < 'examples/md_off.pl'`"
  test 226 -eq "$shar_count" ||
    echo "examples/md_off.pl: original size 226, current size $shar_count"
fi
# ============= examples/md_timer.pl ==============
if test -f 'examples/md_timer.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/md_timer.pl (file already exists)'
else
  echo 'x - extracting examples/md_timer.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/md_timer.pl' &&
#!/usr/local/bin/perl
X
require "/usr/user/kono/src/vbox/visca.pl";
X
package Visca;
X
$dev = '/dev/tty00'; $speed = 9600;
X
&open_visca;
&Dest(1); &VCR_number(3);
X
&send(&VCR('On')); 
&wait;
if(@ARGV) {
X    &send(&VCR(@ARGV)); 
}
&send(&MD('On')); 
&wait;
&send(&MD('Record')); 
X
# end
SHAR_EOF
  $shar_touch -am 0107014996 'examples/md_timer.pl' &&
  chmod 0755 'examples/md_timer.pl' ||
  echo 'restore of examples/md_timer.pl failed'
  shar_count="`wc -c < 'examples/md_timer.pl'`"
  test 283 -eq "$shar_count" ||
    echo "examples/md_timer.pl: original size 283, current size $shar_count"
fi
# ============= examples/test0.pl ==============
if test -f 'examples/test0.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/test0.pl (file already exists)'
else
  echo 'x - extracting examples/test0.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/test0.pl' &&
require "visca.pl";
X
&Visca'test_generator;
# &Visca'list;
SHAR_EOF
  $shar_touch -am 0108174396 'examples/test0.pl' &&
  chmod 0644 'examples/test0.pl' ||
  echo 'restore of examples/test0.pl failed'
  shar_count="`wc -c < 'examples/test0.pl'`"
  test 59 -eq "$shar_count" ||
    echo "examples/test0.pl: original size 59, current size $shar_count"
fi
# ============= examples/vcr_off.pl ==============
if test -f 'examples/vcr_off.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/vcr_off.pl (file already exists)'
else
  echo 'x - extracting examples/vcr_off.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/vcr_off.pl' &&
#!/usr/local/bin/perl
X
require "/usr/user/kono/src/vbox/visca.pl";
X
package Visca;
X
$dev = '/dev/tty00'; $speed = 9600;
X
&open_visca;
&Dest(1); &VCR_number(3);
X
&send(&VCR('Stop')); 
&wait;
&send(&VCR('Off')); 
X
# end
SHAR_EOF
  $shar_touch -am 0107014996 'examples/vcr_off.pl' &&
  chmod 0755 'examples/vcr_off.pl' ||
  echo 'restore of examples/vcr_off.pl failed'
  shar_count="`wc -c < 'examples/vcr_off.pl'`"
  test 218 -eq "$shar_count" ||
    echo "examples/vcr_off.pl: original size 218, current size $shar_count"
fi
# ============= examples/vcr_on.pl ==============
if test -f 'examples/vcr_on.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/vcr_on.pl (file already exists)'
else
  echo 'x - extracting examples/vcr_on.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/vcr_on.pl' &&
#!/usr/local/bin/perl
X
require "/usr/user/kono/src/vbox/visca.pl";
X
package Visca;
X
$dev = '/dev/tty00'; $speed = 9600;
X
&open_visca;
&Dest(1); &VCR_number(3);
X
&send(&VCR('On')); 
&wait;
X
if(@ARGV) {
X    &send(&VCR(@ARGV));
}
X
# end
SHAR_EOF
  $shar_touch -am 0107014996 'examples/vcr_on.pl' &&
  chmod 0755 'examples/vcr_on.pl' ||
  echo 'restore of examples/vcr_on.pl failed'
  shar_count="`wc -c < 'examples/vcr_on.pl'`"
  test 234 -eq "$shar_count" ||
    echo "examples/vcr_on.pl: original size 234, current size $shar_count"
fi
# ============= examples/vcr_reserve.pl ==============
if test -f 'examples/vcr_reserve.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/vcr_reserve.pl (file already exists)'
else
  echo 'x - extracting examples/vcr_reserve.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/vcr_reserve.pl' &&
#!/usr/local/bin/perl
X
require "/usr/user/kono/src/vbox/visca.pl";
X
package Visca;
X
$dev = '/dev/tty00'; $speed = 9600;
X
&open_visca;
&Dest(1); &VCR_number(3);
X
#    &VCRTimerSet("Set Channel 10 on 1/31 from 8:55 to 9:50 LP")
#      BS, SCC, JCSAT, NEW                      
X
&send(
X   &VCRTimerSet(@ARGV)
);
X
# end
SHAR_EOF
  $shar_touch -am 0117001296 'examples/vcr_reserve.pl' &&
  chmod 0755 'examples/vcr_reserve.pl' ||
  echo 'restore of examples/vcr_reserve.pl failed'
  shar_count="`wc -c < 'examples/vcr_reserve.pl'`"
  test 316 -eq "$shar_count" ||
    echo "examples/vcr_reserve.pl: original size 316, current size $shar_count"
fi
# ============= examples/vcr_timer.pl ==============
if test -f 'examples/vcr_timer.pl' && test X"$1" != X"-c"; then
  echo 'x - skipping examples/vcr_timer.pl (file already exists)'
else
  echo 'x - extracting examples/vcr_timer.pl (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'examples/vcr_timer.pl' &&
#!/usr/local/bin/perl
X
require "/usr/user/kono/src/vbox/visca.pl";
X
package Visca;
X
$dev = '/dev/tty00'; $speed = 9600;
X
&open_visca;
&Dest(1); &VCR_number(3);
X
&send(&VCR('On')); 
&wait;
X
&send(&VCR(@ARGV));
&send(&VCR('Record'));
X
# end
SHAR_EOF
  $shar_touch -am 0107014996 'examples/vcr_timer.pl' &&
  chmod 0755 'examples/vcr_timer.pl' ||
  echo 'restore of examples/vcr_timer.pl failed'
  shar_count="`wc -c < 'examples/vcr_timer.pl'`"
  test 239 -eq "$shar_count" ||
    echo "examples/vcr_timer.pl: original size 239, current size $shar_count"
fi
exit 0
